﻿using SC2BuildPlannerLib.Enums;
using System;

namespace SC2BuildPlannerLib.Units
{
    /// <summary>
    /// Class containing all unit data
    /// </summary>
    public class Unit
    {
        /// <summary>
        /// Property for the unit type
        /// </summary>
        private UnitEnum _unitType;
        public UnitEnum UnitType
        {
            get { return _unitType; }
            set { _unitType = value; }
        }

        /// <summary>
        /// Property for whether the unit is a worker
        /// </summary>
        private bool _worker;
        public bool Worker
        {
            get { return _worker; }
            set { _worker = value; }
        }

        /// <summary>
        /// Property for the number of units currently
        /// </summary>
        private int _count;
        public int Count
        {
            get { return _count; }
            set { _count = value; }
        }

        /// <summary>
        /// Property for the number of units that are being produced
        /// </summary>
        private int _countInProduction;
        public int CountInProduction
        {
            get { return _countInProduction; }
            set { _countInProduction = value; }
        }

        /// <summary>
        /// Property for the mineral cost of the unit
        /// </summary>
        private int _mineralCost;
        public int MineralCost
        {
            get { return _mineralCost; }
            set { _mineralCost = value; }
        }

        /// <summary>
        /// Property for the gas cost of the unit
        /// </summary>
        private int _gasCost;
        public int GasCost
        {
            get { return _gasCost; }
            set { _gasCost = value; }
        }

        /// <summary>
        /// Property for the supply cost of the unit
        /// </summary>
        private double _supplyCost;
        public double SupplyCost
        {
            get { return _supplyCost; }
            set { _supplyCost = value; }
        }

        /// <summary>
        /// Property for the time required to produce the unit
        /// </summary>
        private TimeSpan _timeCost;
        public TimeSpan TimeCost
        {
            get { return _timeCost; }
            set { _timeCost = value; }
        }

        /// <summary>
        /// Property for the warpgate cooldown from producing the unit
        /// </summary>
        private TimeSpan? _warpgateTimeCost;
        public TimeSpan? WarpgateTimeCost
        {
            get { return _warpgateTimeCost; }
            set { _warpgateTimeCost = value; }
        }

        /// <summary>
        /// Property for whether the unit is produced in pairs (e.g. Zerglings)
        /// </summary>
        private bool _produceInPairs;
        public bool ProduceInPairs
        {
            get { return _produceInPairs; }
            set { _produceInPairs = value; }
        }

        /// <summary>
        /// Property for the amount of supply provided by the unit
        /// </summary>
        private int _supplyProduced;
        public int SupplyProduced
        {
            get { return _supplyProduced; }
            set { _supplyProduced = value; }
        }

        /// <summary>
        /// Property for the structure/unit from which this unit is produced
        /// </summary>
        private ProductionEnum _producedFrom;
        public ProductionEnum ProducedFrom
        {
            get { return _producedFrom; }
            set { _producedFrom = value; }
        }

        /// <summary>
        /// Property for the structure required to produce the unit
        /// </summary>
        private BuildingEnum? _requiredBuilding;
        public BuildingEnum? RequiredBuilding
        {
            get { return _requiredBuilding; }
            set { _requiredBuilding = value; }
        }

        public Unit(UnitEnum unitType, PatchExpansion patchExpansion)
        {
            UnitType = unitType;

            switch (UnitType)
            {
                case UnitEnum.SCV:
                    Worker = true;
                    Count = 6;
                    MineralCost = 50;
                    SupplyCost = 1;
                    TimeCost = TimeSpan.FromSeconds(17);
                    ProducedFrom = ProductionEnum.CommandCenter;
                    break;
                case UnitEnum.Marine:
                    MineralCost = 50;
                    SupplyCost = 1;
                    TimeCost = TimeSpan.FromSeconds(25);
                    ProducedFrom = ProductionEnum.Barracks;
                    break;
                case UnitEnum.Marauder:
                    MineralCost = 100;
                    GasCost = 25;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(30);
                    ProducedFrom = ProductionEnum.BarracksWithTechLab;
                    break;
                case UnitEnum.Reaper:
                    MineralCost = 50;
                    GasCost = 50;
                    SupplyCost = 1;
                    TimeCost = TimeSpan.FromSeconds(45);
                    ProducedFrom = patchExpansion == PatchExpansion.WingsOfLiberty ? ProductionEnum.BarracksWithTechLab : ProductionEnum.Barracks;
                    break;
                case UnitEnum.Ghost:
                    MineralCost = 200;
                    GasCost = 100;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(40);
                    ProducedFrom = ProductionEnum.BarracksWithTechLab;
                    RequiredBuilding = BuildingEnum.GhostAcademy;
                    break;
                case UnitEnum.TacticalNuke:
                    MineralCost = 100;
                    GasCost = 100;
                    TimeCost = TimeSpan.FromSeconds(60);
                    ProducedFrom = ProductionEnum.GhostAcademy;
                    RequiredBuilding = BuildingEnum.Factory;
                    break;
                case UnitEnum.Hellion:
                    MineralCost = 100;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(30);
                    ProducedFrom = ProductionEnum.Factory;
                    break;
                case UnitEnum.SiegeTank:
                    MineralCost = 150;
                    GasCost = 125;
                    SupplyCost = 3;
                    TimeCost = TimeSpan.FromSeconds(45);
                    ProducedFrom = ProductionEnum.FactoryWithTechLab;
                    break;
                case UnitEnum.Thor:
                    MineralCost = 300;
                    GasCost = 200;
                    SupplyCost = 6;
                    TimeCost = TimeSpan.FromSeconds(60);
                    ProducedFrom = ProductionEnum.FactoryWithTechLab;
                    RequiredBuilding = BuildingEnum.Armory;
                    break;
                case UnitEnum.Hellbat:
                    MineralCost = 100;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(30);
                    ProducedFrom = ProductionEnum.Factory;
                    RequiredBuilding = BuildingEnum.Armory;
                    break;
                case UnitEnum.WidowMine:
                    MineralCost = 75;
                    GasCost = 25;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(40);
                    ProducedFrom = ProductionEnum.Factory;
                    break;
                case UnitEnum.Viking:
                    MineralCost = 150;
                    GasCost = 75;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(42);
                    ProducedFrom = ProductionEnum.Starport;
                    break;
                case UnitEnum.Medivac:
                    MineralCost = 100;
                    GasCost = 100;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(42);
                    ProducedFrom = ProductionEnum.Starport;
                    break;
                case UnitEnum.Banshee:
                    MineralCost = 150;
                    GasCost = 100;
                    SupplyCost = 3;
                    TimeCost = TimeSpan.FromSeconds(60);
                    ProducedFrom = ProductionEnum.StarportWithTechLab;
                    break;
                case UnitEnum.Raven:
                    MineralCost = 100;
                    GasCost = 200;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(60);
                    ProducedFrom = ProductionEnum.StarportWithTechLab;
                    break;
                case UnitEnum.Battlecruiser:
                    MineralCost = 400;
                    GasCost = 300;
                    SupplyCost = 6;
                    TimeCost = TimeSpan.FromSeconds(90);
                    ProducedFrom = ProductionEnum.StarportWithTechLab;
                    RequiredBuilding = BuildingEnum.FusionCore;
                    break;
                case UnitEnum.Drone:
                    Worker = true;
                    Count = 6;
                    MineralCost = 50;
                    SupplyCost = 1;
                    TimeCost = TimeSpan.FromSeconds(17);
                    ProducedFrom = ProductionEnum.Larva;
                    break;
                case UnitEnum.Overlord:
                    Count = 1;
                    MineralCost = 100;
                    SupplyProduced = 8;
                    TimeCost = TimeSpan.FromSeconds(25);
                    ProducedFrom = ProductionEnum.Larva;
                    break;
                case UnitEnum.Overseer:
                    MineralCost = 50;
                    GasCost = 50;
                    TimeCost = TimeSpan.FromSeconds(17);
                    ProducedFrom = ProductionEnum.Overlord;
                    RequiredBuilding = BuildingEnum.Lair;
                    break;
                case UnitEnum.Queen:
                    MineralCost = 150;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(50);
                    ProducedFrom = ProductionEnum.Hatchery;
                    RequiredBuilding = BuildingEnum.SpawningPool;
                    break;
                case UnitEnum.Zergling:
                    MineralCost = 25;
                    SupplyCost = 0.5;
                    TimeCost = TimeSpan.FromSeconds(24);
                    ProduceInPairs = true;
                    ProducedFrom = ProductionEnum.Larva;
                    RequiredBuilding = BuildingEnum.SpawningPool;
                    break;
                case UnitEnum.Baneling:
                    MineralCost = 25;
                    GasCost = 25;
                    SupplyCost = 0.5;
                    TimeCost = TimeSpan.FromSeconds(20);
                    ProducedFrom = ProductionEnum.Zergling;
                    RequiredBuilding = BuildingEnum.BanelingNest;
                    break;
                case UnitEnum.Roach:
                    MineralCost = 75;
                    GasCost = 25;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(27);
                    ProducedFrom = ProductionEnum.Larva;
                    RequiredBuilding = BuildingEnum.RoachWarren;
                    break;
                case UnitEnum.Infestor:
                    MineralCost = 100;
                    GasCost = 150;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(50);
                    ProducedFrom = ProductionEnum.Larva;
                    RequiredBuilding = BuildingEnum.InfestationPit;
                    break;
                case UnitEnum.Hydralisk:
                    MineralCost = 100;
                    GasCost = 50;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(33);
                    ProducedFrom = ProductionEnum.Larva;
                    RequiredBuilding = BuildingEnum.HydraliskDen;
                    break;
                case UnitEnum.Mutalisk:
                    MineralCost = 100;
                    GasCost = 100;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(33);
                    ProducedFrom = ProductionEnum.Larva;
                    RequiredBuilding = BuildingEnum.Spire;
                    break;
                case UnitEnum.Corruptor:
                    MineralCost = 150;
                    GasCost = 100;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(40);
                    ProducedFrom = ProductionEnum.Larva;
                    RequiredBuilding = BuildingEnum.Spire;
                    break;
                case UnitEnum.BroodLord:
                    MineralCost = 150;
                    GasCost = 150;
                    SupplyCost = 4;
                    TimeCost = TimeSpan.FromSeconds(34);
                    ProducedFrom = ProductionEnum.Corruptor;
                    RequiredBuilding = BuildingEnum.GreaterSpire;
                    break;
                case UnitEnum.SwarmHost:
                    MineralCost = 200;
                    GasCost = 100;
                    SupplyCost = 3;
                    TimeCost = TimeSpan.FromSeconds(40);
                    ProducedFrom = ProductionEnum.Larva;
                    RequiredBuilding = BuildingEnum.InfestationPit;
                    break;
                case UnitEnum.Viper:
                    MineralCost = 100;
                    GasCost = 200;
                    SupplyCost = 3;
                    TimeCost = TimeSpan.FromSeconds(40);
                    ProducedFrom = ProductionEnum.Larva;
                    RequiredBuilding = BuildingEnum.Hive;
                    break;
                case UnitEnum.Ultralisk:
                    MineralCost = 300;
                    GasCost = 200;
                    SupplyCost = 6;
                    TimeCost = TimeSpan.FromSeconds(55);
                    ProducedFrom = ProductionEnum.Larva;
                    RequiredBuilding = BuildingEnum.UltraliskCavern;
                    break;
                case UnitEnum.Probe:
                    MineralCost = 50;
                    SupplyCost = 1;
                    TimeCost = TimeSpan.FromSeconds(17);
                    ProducedFrom = ProductionEnum.Nexus;
                    break;
                case UnitEnum.MothershipCore:
                    MineralCost = 100;
                    GasCost = 100;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(30);
                    ProducedFrom = ProductionEnum.Nexus;
                    RequiredBuilding = BuildingEnum.CyberneticsCore;
                    break;
                case UnitEnum.Mothership:
                    MineralCost = patchExpansion == PatchExpansion.WingsOfLiberty ? 400 : 300;
                    GasCost = patchExpansion == PatchExpansion.WingsOfLiberty ? 400 : 300;
                    SupplyCost = 8;
                    TimeCost = patchExpansion == PatchExpansion.WingsOfLiberty ? TimeSpan.FromSeconds(160) : TimeSpan.FromSeconds(100);
                    ProducedFrom = patchExpansion == PatchExpansion.WingsOfLiberty ? ProductionEnum.Nexus : ProductionEnum.MothershipCore;
                    RequiredBuilding = BuildingEnum.FleetBeacon;
                    break;
                case UnitEnum.Zealot:
                    MineralCost = 100;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(38);
                    WarpgateTimeCost = TimeSpan.FromSeconds(28);
                    ProducedFrom = ProductionEnum.Gateway;
                    break;
                case UnitEnum.Stalker:
                    MineralCost = 125;
                    GasCost = 50;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(42);
                    WarpgateTimeCost = TimeSpan.FromSeconds(32);
                    ProducedFrom = ProductionEnum.Gateway;
                    RequiredBuilding = BuildingEnum.CyberneticsCore;
                    break;
                case UnitEnum.Sentry:
                    MineralCost = 50;
                    GasCost = 100;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(37);
                    WarpgateTimeCost = TimeSpan.FromSeconds(32);
                    ProducedFrom = ProductionEnum.Gateway;
                    RequiredBuilding = BuildingEnum.CyberneticsCore;
                    break;
                case UnitEnum.HighTemplar:
                    MineralCost = 50;
                    GasCost = 150;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(55);
                    WarpgateTimeCost = TimeSpan.FromSeconds(45);
                    ProducedFrom = ProductionEnum.Gateway;
                    RequiredBuilding = BuildingEnum.TemplarArchives;
                    break;
                case UnitEnum.DarkTemplar:
                    MineralCost = 125;
                    GasCost = 125;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(55);
                    WarpgateTimeCost = TimeSpan.FromSeconds(45);
                    ProducedFrom = ProductionEnum.Gateway;
                    RequiredBuilding = BuildingEnum.DarkShrine;
                    break;
                case UnitEnum.Archon:
                    SupplyCost = 4;
                    TimeCost = TimeSpan.FromSeconds(12);
                    ProducedFrom = ProductionEnum.TemplarPair;
                    break;
                case UnitEnum.Phoenix:
                    MineralCost = 150;
                    GasCost = 100;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(35);
                    ProducedFrom = ProductionEnum.Stargate;
                    break;
                case UnitEnum.VoidRay:
                    MineralCost = 250;
                    GasCost = 150;
                    SupplyCost = patchExpansion == PatchExpansion.WingsOfLiberty ? 3 : 4;
                    TimeCost = TimeSpan.FromSeconds(60);
                    ProducedFrom = ProductionEnum.Stargate;
                    break;
                case UnitEnum.Carrier:
                    MineralCost = 350;
                    GasCost = 250;
                    SupplyCost = 6;
                    TimeCost = TimeSpan.FromSeconds(120);
                    ProducedFrom = ProductionEnum.Stargate;
                    RequiredBuilding = BuildingEnum.FleetBeacon;
                    break;
                case UnitEnum.Interceptor:
                    MineralCost = 25;
                    TimeCost = TimeSpan.FromSeconds(8);
                    ProducedFrom = ProductionEnum.Carrier;
                    break;
                case UnitEnum.Oracle:
                    MineralCost = 150;
                    GasCost = 150;
                    SupplyCost = 3;
                    TimeCost = TimeSpan.FromSeconds(50);
                    ProducedFrom = ProductionEnum.Stargate;
                    break;
                case UnitEnum.Tempest:
                    MineralCost = 300;
                    GasCost = 200;
                    SupplyCost = 4;
                    TimeCost = TimeSpan.FromSeconds(60);
                    ProducedFrom = ProductionEnum.Stargate;
                    RequiredBuilding = BuildingEnum.FleetBeacon;
                    break;
                case UnitEnum.Observer:
                    MineralCost = 25;
                    GasCost = 75;
                    SupplyCost = 1;
                    TimeCost = TimeSpan.FromSeconds(30);
                    ProducedFrom = ProductionEnum.RoboticsFacility;
                    break;
                case UnitEnum.Immortal:
                    MineralCost = 250;
                    GasCost = 100;
                    SupplyCost = 4;
                    TimeCost = TimeSpan.FromSeconds(55);
                    ProducedFrom = ProductionEnum.RoboticsFacility;
                    break;
                case UnitEnum.WarpPrism:
                    MineralCost = 200;
                    SupplyCost = 2;
                    TimeCost = TimeSpan.FromSeconds(50);
                    ProducedFrom = ProductionEnum.RoboticsFacility;
                    break;
                case UnitEnum.Colossus:
                    MineralCost = 300;
                    GasCost = 200;
                    SupplyCost = 6;
                    TimeCost = TimeSpan.FromSeconds(30);
                    ProducedFrom = ProductionEnum.RoboticsFacility;
                    RequiredBuilding = BuildingEnum.RoboticsBay;
                    break;
            }
        }

        /// <summary>
        /// Method for adding produced units
        /// </summary>
        public void Produce()
        {
            if (ProduceInPairs)
                Count += 2;
            else
                Count++;
        }

        /// <summary>
        /// Method for removing units
        /// </summary>
        public void Remove()
        {
            Count--;
        }

        /// <summary>
        /// Method for resetting the unit to its initial count
        /// </summary>
        public void Reset()
        {
            if (Worker)
                Count = 6;
            else
                Count = 0;
        }
    }
}
